﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System;
using System.IO;
using OpenTK;

using OpenTK.Graphics.OpenGL;
using OpenTK.Audio;

using OpenTK.Input;
using Xeno.Core;
using Xeno.Module;
using Xeno.Physics;
using QuantumEngine;

namespace XenoStudio
{
    public partial class Form1 : Form
    {
        public Dictionary<TreeNode, XenoNode> NodeMap = new Dictionary<TreeNode, XenoNode>();
        public Timer DrawTimer = null;
        public bool Loaded = false;
        public Form1()
        {
            InitializeComponent();


            UpdateTimer = new Timer();
            UpdateTimer.Interval = TickRate;
            UpdateTimer.Tick += new EventHandler(UpdateTimer_Tick);
            //UpdateTimer.Enabled = true;
            UpdateTimer.Start();
            DrawTimer = new Timer();
            DrawTimer.Interval = DrawRate;
            DrawTimer.Tick += new EventHandler(DrawTimer_Tick);
            // DrawTimer.Enabled = true;
            //glControl1.Invalidate();
            DrawTimer.Start();
            //Loaded = true;
        }

        void DrawTimer_Tick(object sender, EventArgs e)
        {

            glControl1.Invalidate();
        }
        public int DrawRate = 1000 / 60;
        public XenoGraph Scene = null;
        public XenoNode SunLight;
        public XenoNode TestModel = null;
        public XenoNode CurEditCam = null;
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            GameManager.StartManager();

            XenoCore.CurrentScene = new XenoGraph("EditScene");
            Scene = XenoCore.CurrentScene;
            XenoCore.CurrentView = XenoFactory.Node.Camera("View Camera", XenoCore.CurrentScene.RootNode);
            XenoCore.CurrentView.LocalPosition = new Vector3(0, 2, 10);
            XenoCore.CurrentView.Rotate(0, 0, 0);
            CurEditCam = XenoCore.CurrentView;

            SunLight = XenoFactory.Light.Directional("SunLight", Scene.RootNode);
            SunLight.LocalPosition = new Vector3(0, 10, 10);
            SunLight.Light.Range = 25;
            SunLight.Light.DiffuseColor = Color.White;
            //TestModel = XenoImport.ImportObj("Content/Model/spider.obj", "Spider", Scene.RootNode, new Vector3(0.1f, 0.1f, 0.1f));
            //TestModel.LocalPosition = new Vector3(0, 0, 0);
            //TestModel.Rotate(0, 0, 0);



            //XenoInput.Init();
            //
            //FrameBufferTarget = new XenoRenderTarget();
            //FrameBuffer = new XenoTexture2D((int)XenoCore.DisplayWidth, (int)XenoCore.DisplayHeight);
            //FrameDepth = new XenoTextureDepth((int)XenoCore.DisplayWidth, (int)XenoCore.DisplayHeight);
            //Filters = new List<XenoFilter>();
            GL.ClearColor(Color.Wheat);
            Loaded = true;
            glControl1_Resize(null, null);
            MakeGrid();
            UpdateTrees();
            UpdateResources();
            RegisterPostFX();
        }

        public Dictionary<string, PostFXCache> FXPool = new Dictionary<string, PostFXCache>();
        public class PostFXCache
        {
            public XenoFilter Filter;
            public string EnglishName;
            public string Help;
            public int ListIndex = -1;
        }
        public void RegisterPostFX()
        {
            FXPool.Clear();
            //LS_FxPool.Items.Clear();
            NewFX("Cinematic Depth Of Field", new Xeno.Filter.FilterDOF(1024), "Add visual depth to your scene by blurring fragments in the distance. A simple varient of the method.");
            NewFX("Cinematic Bloom", new Xeno.Filter.FilterBloom(1024), "Add sparkle to otherwise dim scenes by adding some bloom.");

        }
        public void NewFX(string name, XenoFilter filter, string help)
        {
            PostFXCache cache = new PostFXCache()
            {
                Filter = filter,
                EnglishName = name,
                Help = help
            };
            FXPool.Add(name, cache);
            // LS_FxPool.Items.Add(name);
          //  cache.ListIndex = LS_FxPool.Items.Count - 1;

        }
        public TreeNode NodeModel, NodeGfx, NodeMat, NodeFx;
        public void UpdateResources()
        {
            NodeModel = TreeResource.Nodes["NodeModel"];
            NodeGfx = TreeResource.Nodes["NodeGfx"];
            NodeMat = TreeResource.Nodes["NodeMat"];
            NodeFx = TreeResource.Nodes["NodeFx"];
            AddResources("Content/Model/", NodeModel);
            AddResources("Content/Graphics/", NodeGfx);
            AddResources("Content/Material/", NodeMat);
            AddResources("Content/Shader/", NodeFx);
        }
        public void AddResources(string path, TreeNode node)
        {
            node.Nodes.Clear();
            DirectoryInfo info = new DirectoryInfo(path);
            foreach (var f in info.GetFiles())
            {

                AddResource(node, f.FullName);
            }
            foreach (var d in info.GetDirectories())
            {
                TreeNode dirNode = new TreeNode(d.Name + "/");
                AddResources(d.FullName, dirNode);
                node.Nodes.Add(dirNode);
            }
        }
        public void AddResource(TreeNode parent, string path)
        {
            TreeNode node = new TreeNode(new FileInfo(path).Name);
            node.Name = path;
            parent.Nodes.Add(node);

        }
        public void UpdateTrees()
        {
            TreeScene.Nodes.Clear();
            TreeNode root = new TreeNode("Scene_Root");
            NodeMap.Clear();
            TreeScene.Nodes.Add(root);
            AddNode(root, Scene.RootNode);



        }
        void AddNode(TreeNode treeNode, XenoNode node)
        {
            if (node.HideInEditor) return;
            TreeNode nnode = new TreeNode(node.Name);
            treeNode.Nodes.Add(nnode);
            NodeMap.Add(nnode, node);
            nnode.Checked = node.Active;
            node.UserData = nnode as object;
            foreach (var n in node.Nodes)
            {
                AddNode(nnode, n);
            }
        }

        public int GridSize = 50;
        public float GridSpace = 1.0f;
        public XenoNode Grid;

        public class EditCam
        {
            public static float pitchI = 0, yawI = 0, rollI = 0;
            public static float pitch = 0, yaw = 0, roll = 0;
            public static bool CamLock = false;
            public static float CamDrag = 0.85f;
            public static bool up, down, left, right;
            public static Vector3 Mover = Vector3.Zero;
        }


        public void MakeGrid()
        {

            Grid = XenoFactory.Node.Mesh("Grid", Scene.RootNode);
            XenoMesh msh = Grid.Mesh;
            if (msh == null)
            {
                Environment.Exit(-1);
            }

            float sz = -GridSize * GridSpace;
            float ez = GridSize * GridSpace;
            int vi = 0;
            float gw = 0.1f;
            for (int x = -GridSize; x < GridSize; x++)
            {
                float rx = x * GridSpace;
                XenoVertex v1 = new XenoVertex(new Vector3(rx, 0, sz), Vector3.UnitY, new Vector3(0, 0, 0));
                XenoVertex v2 = new XenoVertex(new Vector3(rx + gw, 0, sz), Vector3.UnitY, new Vector3(1, 0, 0));
                XenoVertex v3 = new XenoVertex(new Vector3(rx + gw, 0, ez), Vector3.UnitY, new Vector3(1, 1, 0));
                XenoVertex v4 = new XenoVertex(new Vector3(rx, 0, ez), Vector3.UnitY, new Vector3(0, 1, 0));
                msh.AddVertex = v1;
                msh.AddVertex = v2;
                msh.AddVertex = v3;
                msh.AddVertex = v4;
                msh.AddTriangle = new XenoTriangle(vi, vi + 1, vi + 2);
                msh.AddTriangle = new XenoTriangle(vi + 2, vi + 3, vi);
                vi += 4;
                float ry = x * GridSpace;
                v1 = new XenoVertex(new Vector3(sz, 0, ry), Vector3.UnitY, new Vector3(0, 0, 0));
                v2 = new XenoVertex(new Vector3(sz, 0, ry + gw), Vector3.UnitY, new Vector3(1, 0, 0));
                v3 = new XenoVertex(new Vector3(ez, 0, ry + gw), Vector3.UnitY, new Vector3(1, 1, 0));
                v4 = new XenoVertex(new Vector3(ez, 0, ry), Vector3.UnitY, new Vector3(0, 1, 0));
                msh.AddVertex = v1;
                msh.AddVertex = v2;
                msh.AddVertex = v3;
                msh.AddVertex = v4;
                msh.AddTri(vi, vi + 1, vi + 2);
                msh.AddTri(vi + 2, vi + 3, vi);
                vi += 4;

            }
           
            msh.FlipNormals = false;
            msh.UpdateNormals();
            Grid.Active = true;

            XenoMaterial floorMat = new XenoMaterial("FloorMat");

            floorMat.NoLit = true;
            floorMat.DiffuseColor = new Vector4(0.25f, 0.25f, 0.25f, 1.0f);

            // floorMat.DiffuseMap = new XenoTexture2D("Content/Material/Brick_Diffuse.jpg");
            //   floorMat.NormalMap = new XenoTexture2D("Content/Material/Brick_Normal.jpg");


            Grid.HideInEditor = true;
            Grid.MeshRenderer.Material = floorMat;
            // List<XenoNode> nodes = TestModel.AllWithType(typeof(XenoMeshRenderer), null);

            // foreach (var n in nodes)
            // {

            // n.MeshRenderer.Material = floorMat;

            //}



        }

        void glControl1_Paint(object sender, PaintEventArgs e)
        {


        }
        float debugX = 0, debugY = 0;
        void UpdateTimer_Tick(object sender, EventArgs e)
        {

            //debugX++;
            if (XenoCore.CurrentScene == null) return;
            //Environment.Exit(-1);

            EditCam.pitch += EditCam.pitchI;
            EditCam.yaw += EditCam.yawI;
            EditCam.roll += EditCam.rollI;

            EditCam.rollI *= EditCam.CamDrag;
            EditCam.yawI *= EditCam.CamDrag;
            EditCam.pitchI *= EditCam.CamDrag;

            XenoCore.CurrentView.Rotate(EditCam.pitch, EditCam.yaw, EditCam.roll);

            XenoCore.CurrentScene.UpdateGraph();
            Vector3 mov = Vector3.Zero;
            if (EditCam.CamLock)
            {

                float movSpd = 0.2f;
                if (PlaceLock)
                {
                    movSpd *= 0.1f;
                }
                if (EditCam.up)
                {
                    mov = new Vector3(0, 0, -movSpd);
                }
                if (EditCam.down)
                {
                    mov = new Vector3(0, 0, movSpd);
                }
                if (EditCam.left)
                {
                    mov += new Vector3(-movSpd, 0, 0);
                }
                if (EditCam.right)
                {
                    mov += new Vector3(movSpd, 0, 0);
                }

                if (mov.Length > 0)
                {
                    mov = Vector3.TransformVector(mov, Matrix4.Invert(XenoCore.CurrentView.WorldMatrix));
                }
            }

            EditCam.Mover = EditCam.Mover + mov;

            EditCam.Mover.X *= EditCam.CamDrag;
            EditCam.Mover.Y *= EditCam.CamDrag;
            EditCam.Mover.Z *= EditCam.CamDrag;

            //EditCam.Mover /= 1;

            //  EditCam.Mover = Vector3.Zero;

            XenoCore.CurrentView.LocalPosition += EditCam.Mover;
            UpdateNode(Scene.RootNode);
            UpdateActiveModules();
          //  UpdateNodeEditor(ActiveNode());
            //debugX += 20;

        }
        
        void UpdateNode(XenoNode node)
        {

            TreeNode tnode = node.UserData as TreeNode;
            if (tnode != null)
            {
                tnode.Checked = node.Active;



                foreach (var n in node.Nodes)
                {
                    UpdateNode(n);
                }
            }
        }
        Timer UpdateTimer;

        public int TickRate = 1000 / 60;
        void Form1_Resize(object sender, EventArgs e)
        {

        }



        private void splitContainer2_SplitterMoved(object sender, SplitterEventArgs e)
        {

        }

        private void glControl1_Load(object sender, EventArgs e)
        {

        }

        private void glControl1_Paint_1(object sender, PaintEventArgs e)
        {
            if (XenoCore.CurrentScene == null)
            {
                return;
            }
            XenoCore.CurrentView = CurEditCam;
            GL.Viewport(glControl1.ClientRectangle);
            // Environment.Exit(-1);
            glControl1.MakeCurrent();
            GL.ClearColor(Color.Black);
         
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
            XenoCore.LightList = Scene.RootNode.AllWithType(typeof(XenoMod_Light), null);
            Scene.RenderGraph();

            glControl1.SwapBuffers();


        }
        public bool PlaceLock = false;
        private void glControl1_Resize(object sender, EventArgs e)
        {
            
            XenoCore.DisplayWidth = glControl1.ClientRectangle.Width;
            XenoCore.DisplayHeight = glControl1.ClientRectangle.Height;
            //Matrix4 projection = Matrix4.Perspective((float)Math.PI / 4, Width / (float)Height, 1.0f, 64.0f);

            //    GL.MatrixMode(MatrixMode.Projection);
            //  GL.LoadMatrix(ref projection);
        }

        private void glControl1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                EditCam.CamLock = true;
            }
            if (e.Button == MouseButtons.Left)
            {
                CastHit hit = XenoCore.CurrentView.Camera.Pick(lastx, lasty);
                if (PlaceLock)
                {
                   
                    if (hit != null && hit.Hit)
                    {
                        XenoNode an = ActiveNode();
                        if (an == null)
                        {
                            return;
                        }
                        an.LocalPosition = hit.ImpactPoint;

                    }
                }
                else
                {
                    if (hit != null && hit.Hit)
                    {
                        
                        XenoNode node = hit.ImpactNode;
                        if (node != null)
                        {
                            TreeScene.SelectedNode = node.UserData as TreeNode;
                            UpdateNodeEditor(node);
                        }
                    }
                }
            }
        }

        private void glControl1_MouseLeave(object sender, EventArgs e)
        {

        }

        private void glControl1_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                EditCam.CamLock = false;
            }
        }
        bool first = true;
        int lastx, lasty;
        float xi, yi;

        private void glControl1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            if (first)
            {
                lastx = e.X;
                lasty = e.Y;
                first = false;
            }

            int xi, yi;
            xi = e.X - lastx;
            yi = e.Y - lasty;
            lastx = e.X;
            lasty = e.Y;

            if (EditCam.CamLock)
            {


                EditCam.pitchI -= yi * 0.1f;
                EditCam.yawI -= xi * 0.1f;


            }
        }

        private void glControl1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.ShiftKey) 
            {
          
                PlaceLock = true;
            }
            if (e.KeyCode == Keys.W)
            {
                EditCam.up = true;
            }
            if (e.KeyCode == Keys.S)
            {
                EditCam.down = true;
            }
            if (e.KeyCode == Keys.A)
            {
                EditCam.left = true;
            }
            if (e.KeyCode == Keys.D)
            {
                EditCam.right = true;
            }
        }

        private void glControl1_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.ShiftKey)
            {
                PlaceLock = false;
            }
            if (e.KeyCode == Keys.W)
            {
                EditCam.up = false;
            }
            if (e.KeyCode == Keys.S)
            {
                EditCam.down = false;
            }
            if (e.KeyCode == Keys.A)
            {
                EditCam.left = false;
            }
            if (e.KeyCode == Keys.D)
            {
                EditCam.right = false;
            }
        }

        private void TreeScene_AfterCheck(object sender, TreeViewEventArgs e)
        {
            if (NodeMap.ContainsKey(e.Node) == false) return;
            XenoNode node = NodeMap[e.Node];
            node.Active = e.Node.Checked;
        }

        private void pyramidToolStripMenuItem_Click(object sender, EventArgs e)
        {
            XenoNode newNode = NewAt();

            XenoFactory.Mesh.Pyramid(newNode, 1);
            newNode.Mesh.UpdateNormals();
            UpdateTrees();

        }

        private XenoNode NewAt()
        {
            Vector3 at = Vector3.TransformPosition(new Vector3(0, 0, -5), Matrix4.Invert(XenoCore.CurrentView.WorldMatrix));
            XenoNode newNode = XenoFactory.Node.Mesh("New Prefab", Scene.RootNode);
            newNode.LocalPosition = at;
            return newNode;
        }

        private void TreeResource_AfterSelect(object sender, TreeViewEventArgs e)
        {

        }

        private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
        {

        }
        public XenoNode ImportResource(string path)
        {
            FileInfo info = new FileInfo(path);
            //XenoNode n1 = ResourceImporter.ImportResource(path, null);
            XenoNode n1 = XenoImport.ImportAI(path, path, Scene.RootNode, 1.0f);
            PlaceAt(n1);
            UpdateTrees();
            return n1;
            

        }

        private static void PlaceAt(XenoNode n1)
        {
            Vector3 at = Vector3.TransformPosition(new Vector3(0, 0, -5), Matrix4.Invert(XenoCore.CurrentView.WorldMatrix));
            n1.LocalPosition = at;
        }
        private void toolStripMenuItem1_Click(object sender, EventArgs e)
        {
            if (TreeResource.SelectedNode == null)
            {
                MessageBox.Show("Nothing selected to import.", "XenoIDE");
                return;
            }
            TreeNode res = TreeResource.SelectedNode;
            if (File.Exists(res.Name))
            {
                FileInfo info = new FileInfo(res.Name);
                if (info != null && info.Exists)
                {

                    XenoNode node = ImportResource(res.Name);
                }

                else
                {
                    MessageBox.Show("Unable to import non valid file:" + res.Name, "XenoIDE");

                }

            }
        }

        private void managerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            XenoNode add;
            add = ActiveNode();
            if (add == null)
            {
                MessageBox.Show("No active Node", "XenoIDE");
                return;
            }
            add.AddModule = new XenoPhysicsManager("PhysicsManager");

        }

        private XenoNode ActiveNode()
        {
            XenoNode add = null;
            TreeNode node = TreeScene.SelectedNode;
            if (node == null)
            {
                return null;
            }
            if (NodeMap.ContainsKey(node))
            {
                add = NodeMap[node];
            }
            return add;
        }

        /// <summary>
        /// Physics Manager
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void physicsManagerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            XenoNode pMan = new XenoNode("PhysicsManager", Scene.RootNode);
            pMan.AddModule = new XenoPhysicsManager("PhysicsManager");
            UpdateTrees();
        }
        //CubeCollider
        private void toolStripMenuItem2_Click(object sender, EventArgs e)
        {
                XenoNode add;
                add = ActiveNode();
                if (add == null)
                {
                    MessageBox.Show("No active Node", "XenoIDE");
                    return;
                }
                XenoFactory.Physics.Cube(add, 1);
           
        }

        private void physicsEnabledFloorToolStripMenuItem_Click(object sender, EventArgs e)
        {
            XenoNode flr = XenoFactory.Node.Mesh("Floor", Scene.RootNode);
            XenoMesh msh = flr.Mesh;

            XenoVertex v1 = new XenoVertex(new Vector3(-100, -0.1f, -100), new Vector3(0, 1, 0), new Vector3(0, 0, 0));
            XenoVertex v2 = new XenoVertex(new Vector3(100, -0.1f, -100), new Vector3(0, 1, 0), new Vector3(1, 0, 0));
            XenoVertex v3 = new XenoVertex(new Vector3(100, -0.1f, 100), new Vector3(0, 1, 0), new Vector3(1, 1, 0));
            XenoVertex v4 = new XenoVertex(new Vector3(-100, -0.1f, 100), new Vector3(0, 1, 0), new Vector3(0, 1, 0));

            msh.AddVertices = new XenoVertex[] { v1, v2, v3, v4 };

            msh.AddTri(0, 1, 2);
            msh.AddTri(2, 3, 0);

            msh.FlipNormals = true;

            XenoFactory.Physics.Mesh(flr);


        }

        private void TreeScene_AfterSelect(object sender, TreeViewEventArgs e)
        {
            XenoNode node = ActiveNode();
            UpdateModuleEditor(node);
            UpdateModulePanel();
        }
        public List<ModuleEditor> Editors = new List<ModuleEditor>();
        public void UpdateActiveModules()
        {
            XenoNode aNode = ActiveNode();
            if (aNode == null) return;
            foreach (var e in Editors)
            {
                if (e.FlagForDelete)
                {
                    aNode.Modules.Remove(e.Module);
                    UpdateModulePanel();
                    return;
                }
            }
        }
        public class PropNode
        {
            public Control c1, c2, c3, c4, c5, c6;
            public System.Reflection.PropertyInfo prop;
            public XenoModule mod;
        }
        public Dictionary<Control, PropNode> PropMap = new Dictionary<Control, PropNode>();
        public void UpdateModulePanel()
        {
            PropMap.Clear();
            foreach (var e in Editors)
            {
                ModuleSplit.Panel2.Controls.Remove(e);

            }
            Editors.Clear();
            XenoNode aNode = ActiveNode();
            if (aNode == null) return;
  
            int mc = aNode.Modules.Count;
            int py = mc * 200;
   
            float ay = 0;

            foreach (var mod in aNode.Modules)
            {
                ModuleEditor me = new ModuleEditor();
                ModuleSplit.Panel2.Controls.Add(me);
                me.Location = PN_Node.Location;
                me.Location = new Point(me.Location.X, me.Location.Y + 200+(int)ay);
                me.InitialY = me.Location.Y;
                me.SetLabel(mod.Name);
                me.Module = mod;

                Type typ = mod.GetType();
                float eh = typ.GetProperties().GetLength(0) * 60;
                me.SetHeight((int)eh+60);
               
                int xy = 0;
                foreach (var p in typ.GetProperties())
                {

                    Label propLab = new Label();
                    propLab.Text = "Property--[ " + p.Name + " ]--";
                    if (propLab.Text.Length > 32)
                    {
                        propLab.Text = " Property--[ <Invalid> ]--";
                    }
                    propLab.Location = new Point(5, 35+xy);
                    me.AddControl(propLab);
                    propLab.Size = new Size(120, 16);
                    propLab.BackColor = Color.BlanchedAlmond;
                    PropNode pNode = new PropNode();
                    pNode.prop = p;
                    pNode.mod = mod;
                    if (typeof(float) == p.PropertyType)
                    {
                        TextBox tb = new TextBox();
                        tb.Location = new Point(10, 35 + xy + 20);
                        tb.Size = new Size(80, 20);
                        tb.Text = p.GetValue(mod, null).ToString();
                        tb.TextChanged += new EventHandler(tb_TextChanged);
                        me.AddControl(tb);
                        PropMap[tb] = pNode;
                    }
                    if (typeof(bool) == p.PropertyType)
                    {
                        CheckBox tbool = new CheckBox();
                        tbool.Location = new Point(10, 35 + xy + 20);
                        tbool.Text = "Enable";
                        tbool.CheckedChanged += new EventHandler(tbool_CheckedChanged);
                        me.AddControl(tbool);
                        PropMap[tbool] = pNode;
                        tbool.Checked = (bool)p.GetValue(mod as object, null);
                    }
                    if (typeof(Vector3) == p.PropertyType)
                    {
                        TextBox tx = new TextBox();
                        tx.Location = new Point(10, 35 + xy + 20);
                        tx.Size = new Size(40, 20);
                        Vector3 vec = (Vector3)p.GetValue(mod, null);
                        tx.Text = vec.X.ToString();
                        tx.TextChanged += new EventHandler(tx_TextChanged);
                        TextBox ty = new TextBox();
                        ty.Location = new Point(60, 35 + xy + 20);
                        ty.Size = new Size(40, 20);
                        ty.Text = vec.Y.ToString();
                        ty.TextChanged += new EventHandler(ty_TextChanged);
                        TextBox tz = new TextBox();
                        tz.Location = new Point(110, 35 + xy + 20);
                        tz.Size = new Size(40, 20);
                        tz.Text = vec.Z.ToString();
                        tz.TextChanged += new EventHandler(tz_TextChanged);
                        PropMap[tx] = pNode;
                        PropMap[ty] = pNode;
                        PropMap[tz] = pNode;
                        me.AddControl(tx);
                        me.AddControl(ty);
                        me.AddControl(tz);
                    }
                    xy += 60;
                }

                Editors.Add(me);
                ay += 80+xy;
            }
            
            UpdateModulePanelPosition();
            Refresh();
        }

        void tbool_CheckedChanged(object sender, EventArgs e)
        {

            CheckBox tb = sender as CheckBox;
            if (tb == null)
            {
                Environment.Exit(-1);
            }

            if (PropMap.ContainsKey(sender as Control))
            {

                PropNode pNode = PropMap[sender as Control];
                pNode.prop.SetValue(pNode.mod, tb.Checked, null);

            }
        }

        void ty_TextChanged(object sender, EventArgs e)
        {
            TextBox tb = sender as TextBox;
            if (tb == null)
            {
                Environment.Exit(-1);
            }

            if (PropMap.ContainsKey(sender as Control))
            {

                PropNode pNode = PropMap[sender as Control];
                Vector3 v = (Vector3)pNode.prop.GetValue(pNode.mod as object, null);
                v.Y = float.Parse(tb.Text);
                pNode.prop.SetValue(pNode.mod, (object)v, null);

            }
        }

        void tx_TextChanged(object sender, EventArgs e)
        {
            TextBox tb = sender as TextBox;
            if (tb == null)
            {
                Environment.Exit(-1);
            }

            if (PropMap.ContainsKey(sender as Control))
            {

                PropNode pNode = PropMap[sender as Control];
                Vector3 v = (Vector3)pNode.prop.GetValue(pNode.mod as object, null);
                v.X = float.Parse(tb.Text);
                pNode.prop.SetValue(pNode.mod, (object)v, null);

            }
        }

        void tz_TextChanged(object sender, EventArgs e)
        {
            TextBox tb = sender as TextBox;
            if (tb == null)
            {
                Environment.Exit(-1);
            }

            if (PropMap.ContainsKey(sender as Control))
            {
               
                PropNode pNode = PropMap[sender as Control];
                Vector3 v = (Vector3)pNode.prop.GetValue(pNode.mod as object, null);
                v.Z = float.Parse(tb.Text);
                pNode.prop.SetValue(pNode.mod, (object)v, null);
        
            }
        }

        void tb_TextChanged(object sender, EventArgs e)
        {
       
            TextBox tb = sender as TextBox;
            if (tb == null)
            {
                Environment.Exit(-1);
            }

            if (PropMap.ContainsKey(sender as Control))
            {
           
                PropNode pNode = PropMap[sender as Control];
                pNode.prop.SetValue(pNode.mod, float.Parse(tb.Text), null);
 
            }
        }
        public void UpdateModulePanelPosition()
        {
         
        }

        public void UpdateModuleEditor(XenoNode node)
        {
            UpdateNodeEditor(node);
        }
        public void UpdateNodeFromEditor(XenoNode node)
        {
            if (node == null) return;
            Vector3 pos = Vector3.Zero;
            try
            {
                pos.X = float.Parse(TB_X.Text);
            }
            catch
            {
            }
            try
            {
                pos.Y = float.Parse(TB_Y.Text);
            }
            catch
            {
            }
            try
            {
                pos.Z = float.Parse(TB_Z.Text);
            }
            catch
            {
            }
            Vector3 scal = Vector3.Zero;
            scal = node.LocalScale;

            try
            {
                scal.X = float.Parse(TB_ScaleX.Text);
            }
            catch
            {
            }
            try
            {
                scal.Y = float.Parse(TB_ScaleY.Text);
            }
            catch
            {
            }
            try
            {
                scal.Z = float.Parse(TB_ScaleZ.Text);
            }
            catch
            {
            }
            node.LocalScale = scal;
            node.LocalPosition = pos;
        }
        private void UpdateNodeEditor(XenoNode node)
        {
            if (node == null) return;
            Vector3 pos = node.LocalPosition;
            Vector3 scal = node.LocalScale;
            TB_X.Text = "" + pos.X;
            TB_Y.Text = "" + pos.Y;
            TB_Z.Text = "" + pos.Z;
            TB_ScaleX.Text = "" + scal.X;
            TB_ScaleY.Text = "" + scal.Y;
            TB_ScaleZ.Text = "" + scal.Z;

        }

        private void TB_X_TextChanged(object sender, EventArgs e)
        {
            UpdateNodeFromEditor(ActiveNode());
        }

        private void TB_Y_TextChanged(object sender, EventArgs e)
        {
            UpdateNodeFromEditor(ActiveNode());
        }

        private void TB_Z_TextChanged(object sender, EventArgs e)
        {
            UpdateNodeFromEditor(ActiveNode());
        }

        private void TB_Pitch_TextChanged(object sender, EventArgs e)
        {
            UpdateNodeFromEditor(ActiveNode());
        }

        private void TB_Yaw_TextChanged(object sender, EventArgs e)
        {
            UpdateNodeFromEditor(ActiveNode());
        }

        private void TB_Roll_TextChanged(object sender, EventArgs e)
        {
            UpdateNodeFromEditor(ActiveNode());
        }

        private void TB_ScaleX_TextChanged(object sender, EventArgs e)
        {
            UpdateNodeFromEditor(ActiveNode());
        }

        private void TB_ScaleY_TextChanged(object sender, EventArgs e)
        {
            UpdateNodeFromEditor(ActiveNode());
        }

        private void TB_ScaleZ_TextChanged(object sender, EventArgs e)
        {
            UpdateNodeFromEditor(ActiveNode());
        }

        private void ModuleScroll_Scroll(object sender, ScrollEventArgs e)
        {
            UpdateModulePanelPosition();
        }

        private void listBox2_SelectedIndexChanged(object sender, EventArgs e)
        {

        }
        public Dictionary<string, PostFXCache> FXActive = new Dictionary<string, PostFXCache>();

        private void button2_Click(object sender, EventArgs e)
        {
            //string item = LS_FxPool.SelectedItem as string;
            /*
            if (item == "")
            {
                return;
            }
            if (item == null)
            {
                return;
            }
            if (FXPool.ContainsKey(item))
            {
                PostFXCache cache = FXPool[item];
                FXPool.Remove(item);
                FXActive.Add(cache.EnglishName, cache);
                LS_FxPool.Items.Remove(item);
                LS_ActiveFx.Items.Add(item);
            }
            else
            {
                MessageBox.Show("Unknown PostFX, has not been registered. Please report this bug to the developer.", "XenoIDE");
            }
            UpdateFxSettings();
            
             */ }

        public void UpdateFxSettings()
        {
            Scene.Filters.Clear();
            foreach (var m in FXActive.Values)
            {
                Scene.AddFilter = m.Filter;
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            /*
            string item = LS_ActiveFx.SelectedItem as string;
            if (item == "")
            {
                return;
            }
            if (item == null)
            {
                return;
            }
            if (FXActive.ContainsKey(item))
            {
                PostFXCache cache = FXActive[item];
                FXActive.Remove(item);
                FXPool.Add(cache.EnglishName, cache);
                LS_ActiveFx.Items.Remove(item);
                LS_FxPool.Items.Add(item);
            }
            else
            {
                MessageBox.Show("Unknown PostFX, has not been registered. Please report this bug to the developer.", "XenoIDE");
            }
            UpdateFxSettings();
        
             */
        }

        private void quantumEventEditorToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            QuantumEditor.OpenEditor();
        }

        private void Form1_Load(object sender, System.EventArgs e)
        {
            ResourceImporter.RegisterStandardImporters();
            XenoFX.InitXenoFX();
        }

        private NardoVinchi Nardo = null;
        private void materialEditorToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            Nardo = new NardoVinchi();
            Nardo.Show();
        }
    }


  
}

